﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;

namespace Sinacor.Infra.UI.Controls.SmartClient
{
    internal static class FrameworkElementExtensionMethods
    {
        /// <summary>
        /// Recuperar o hashcode do objeto source do binding
        /// e caso n encontre retornar o dataContext do elemento
        /// </summary>
        /// <param name="element"></param>
        /// <param name="bind"></param>
        /// <returns></returns>
        internal static int? GetHashCodeOfSourceObject(this FrameworkElement element, Binding bind)
        {
            //TODO: Implementar busca do objeto source do binding para as propriedade ElementName e RelativeSource
            //não foi implementado nesse momento pois via regra o binding será realizado com uma model
            if (bind != null)
            {
                if (bind.Source != null)
                    return bind.Source.GetHashCode();

                if (bind.ElementName != null)
                    return null;

                if (bind.RelativeSource != null)
                    return null;
            }
            
            if (element.DataContext != null)
            {
                return element.DataContext.GetHashCode();
            }

            return null;
        }

        /// <summary>
        /// Recupera o ResourceKey a partir de uma DependencyProperty
        /// </summary>
        /// <param name="element"></param>
        /// <param name="dp"></param>
        /// <returns></returns>
        public static string GetResourceReference(this FrameworkElement element, DependencyProperty dp)
        {
            ResourceReferenceExpressionConverter converter = new ResourceReferenceExpressionConverter();

            object expr = GetLocalValue(element, dp);

            DynamicResourceExtension dre = converter.ConvertTo(expr, typeof(MarkupExtension)) as DynamicResourceExtension;

            return dre.ResourceKey as string;
        }

        /// <summary>
        /// Recupera o ResourceExpression a partir da DependencyProperty
        /// </summary>
        /// <param name="d"></param>
        /// <param name="dp"></param>
        /// <returns></returns>
        private static object GetLocalValue(DependencyObject d, DependencyProperty dp)
        {
            LocalValueEnumerator e = d.GetLocalValueEnumerator();

            while (e.MoveNext())
            {
                if (e.Current.Property == dp)
                {
                    return e.Current.Value;
                }
            }

            return null;
        }
    }
}
